package com.alibaba.citrus.cr.sales.plan.facade.service.setting;

import com.alibaba.acm.shaded.com.alibaba.metrics.StringUtils;
import com.alibaba.acm.shaded.com.google.common.collect.Maps;
import com.alibaba.citrus.cr.common.annotation.EpochTransactional;
import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.common.model.epoch.EpochQueryPlanScItemScopeCrossDomainMatchReq;
import com.alibaba.citrus.cr.common.model.epoch.EpochQueryPlanScItemScopeCrossDomainMatchResp;
import com.alibaba.citrus.cr.common.util.CalculatePercentage;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.citrus.cr.common.util.EpochRESTClient;
import com.alibaba.citrus.cr.sales.plan.annotation.CommonRedisLock;
import com.alibaba.citrus.cr.sales.plan.api.salesplan.SalesPlanQueryService;
import com.alibaba.citrus.cr.sales.plan.api.setting.SalesPlanScItemWriteService;
import com.alibaba.citrus.cr.sales.plan.contants.SalesPlanConstants;
import com.alibaba.citrus.cr.sales.plan.contants.SalesPlanLockKey;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.BatchEditCostInsuranceFreightRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.BatchUpdateScItemStatusRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.PageQueryPlanAdjustDetailRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.PageQueryPlanLineRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.QuerySalesPlanRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.SalesPlanScItemPageQueryRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.SalesPlanScItemQueryRequest;
import com.alibaba.citrus.cr.sales.plan.facade.service.SalesPlanOutCommonService;
import com.alibaba.citrus.cr.sales.plan.functions.salesplanscitem.SalesPlanScItemEntity;
import com.alibaba.citrus.cr.sales.plan.model.enums.SalesPlanModelEnum;
import com.alibaba.citrus.cr.sales.plan.model.enums.SalesPlanStatusEnum;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanAdjustDetailRepository;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanLineRepository;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanScItemRepository;
import com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanAdjustDetailSDO;
import com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanLineSDO;
import com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanSDO;
import com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanScItemSDO;
import com.alibaba.citrus.cr.sales.plan.api.statistics.SalesPlanStatService;
import com.alibaba.citrus.cr.sales.plan.facade.service.SalesPlanCommonService;
import com.alibaba.cz.base.tool.StringUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.middleware.cache.runtime.service.EpochCacheService;
import com.alibaba.lattice2.epoch.middleware.mq.runtime.EpochMessageService;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.contants.BcOrderConstants;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByIdsRequest;
import com.epoch.app.bcorder.model.dto.BatchQueryCompanyRequest;
import com.epoch.app.bcorder.sales_plan.bosalesplandetailindex.dto.GetScitemByStatusRequest;
import com.epoch.app.bcorder.sales_plan.bosalesplandetailindex.service.BoSalesPlanDetailIndexService;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.BcOrderService;
import com.epoch.app.crplatformenhance.api.organizationquery.dto.QuerySuperiorSalesOrganizationRequest;
import com.epoch.app.crplatformenhance.api.organizationquery.service.OrganizationQueryService;
import com.epoch.app.crplatformenhance.model.dto.PageQueryCustomerScope2Request;
import com.epoch.app.crplatformenhance.model.dto.PageQueryCustomerScope2Response;
import com.epoch.app.crplatformenhance.model.dto.ScItemSDO;
import com.epoch.app.crplatformenhance.sdo.CustomerSaleScopeSDO;
import com.epoch.app.crplatformenhance.sdo.OrganizationSDO;
import com.epoch.app.crplatformenhance.service.CrPlatformEnhanceService;
import com.epoch.app.crpricecenter.api.pricequery.service.PriceQueryService;
import com.epoch.app.crpricecenter.dto.request.DimensionPropertyInfoRequest;
import com.epoch.app.crpricecenter.dto.request.HumanInfoRequest;
import com.epoch.app.crpricecenter.dto.request.MaterialInfoRequest;
import com.epoch.app.crpricecenter.dto.request.PlaceInfoRequest;
import com.epoch.app.crpricecenter.dto.request.PriceQueryRequest;
import com.epoch.app.crpricecenter.dto.response.ItemPriceResponse;
import com.epoch.app.crpricecenter.dto.response.PriceQueryResponse;
import com.epoch.app.crpricecenter.model.enums.PriceTypeEnum;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.alibaba.citrus.cr.common.constant.EpochRESTPathConstants.QUERY_PLAN_SCITEM_SCOPE_CROSS_DOMAIN_MATCH;

/**
 * @author wangyibing
 */
@Service
public class SalesPlanScItemWriteServiceImpl implements SalesPlanScItemWriteService {
    private static final Log log = Log.getLogger(SalesPlanScItemWriteServiceImpl.class);

    @Autowired
    private EpochRESTClient epochRESTClient;

    @Resource
    private SalesPlanScItemRepository salesPlanScItemRepository;

    @Autowired(required = false)
    private PriceQueryService priceQueryService;

    @Autowired(required = false)
    private OrganizationQueryService organizationQueryService;

    @Resource
    private BaseDataService baseDataService;

    @Resource
    private SalesPlanQueryService salesPlanQueryService;

    @Resource
    private SalesPlanLineRepository salesPlanLineRepository;

    @Resource
    private SalesPlanAdjustDetailRepository salesPlanAdjustDetailRepository;

    @Resource
    private BoSalesPlanDetailIndexService boSalesPlanDetailIndexService;

    @Resource
    private CrPlatformEnhanceService crPlatformEnhanceService;

    @Resource
    private EpochMessageService messageService;

    @Resource
    private EpochCacheService epochCacheService;

    @Resource
    private SalesPlanStatService salesPlanStatService;

    @Resource
    private SalesPlanOutCommonService salesPlanOutCommonService;

    /**
     * 计划明细page_size
     */
    private static final Integer SALES_PLAN_LIN_PAGE_SIZE = 500;

    /**
     * 计划调整明细page_size
     */
    private static final Integer SALES_PLAN_ADJUST_PAGE_SIZE = 500;

    //按每50个一组分割
    private static final Integer MAX_NUMBER = 50;

    @Resource
    private BcOrderService bcOrderService;

    private static final Integer ZERO = 0;

    private static final Integer ONE_HUNDRED = 100;

    private static final Integer ONE_THOUSAND = 1000;

    @FacadeInvoker
    @Override
    @EpochTransactional(appCode = "bc_order", dataSourceCode = "cr_ots", dataSourceType = "app")
    public Result<List<String>> batchCreateSalesPlanScItem(List<SalesPlanScItemSDO> productPlanSDOs) {
        ArrayList<String> ids = new ArrayList<>();
        productPlanSDOs.forEach(sdo -> {
            SalesPlanScItemEntity salesPlanScItemEntity = SalesPlanScItemEntity.of(sdo);
            String id = salesPlanScItemEntity.doCreate();
            if (StringUtil.isNotEmpty(id)) {
                ids.add(id);
            }
        });
        return Result.success(ids);
    }

    @FacadeInvoker
    @Override
    @CommonRedisLock(redisLockPrefix = SalesPlanLockKey.CREATE_SALES_PLAN_SC_ITEM_PREFIX)
    public Result<String> createSalesPlanScItem(SalesPlanScItemSDO salesPlanScItemSDO) {
        // 校验分子公司创建计划货品不可超出总部设置范围
        boolean isFail = checkScItemScope(salesPlanScItemSDO);
        if (isFail) {
            return Result.fail(null,"分子公司创建计划货品不可超出总部设置范围");
        }

        // 获取价格(常规价,到岸价)
        long start = System.currentTimeMillis();
        getPrice(salesPlanScItemSDO);
        log.info("创建计划货品获取常规价和到岸价耗时:{}", System.currentTimeMillis() - start);
        SalesPlanScItemEntity salesPlanScItemEntity = SalesPlanScItemEntity.of(salesPlanScItemSDO);
        SalesPlanScItemPageQueryRequest pageQueryRequest = new SalesPlanScItemPageQueryRequest();
        BeanUtils.copyProperties(salesPlanScItemSDO, pageQueryRequest);
        PageResult<List<SalesPlanScItemSDO>> listPageResult = salesPlanScItemRepository.pageQuerySalesPlanScItemList(pageQueryRequest);
        // 如果存在该货品就更新
        String id;
        if (CollectionUtils.isNotEmpty(listPageResult.getContent())) {
            SalesPlanScItemSDO itemSDO = listPageResult.getContent().stream().findFirst().get();
            salesPlanScItemSDO.setId(itemSDO.getId());
            salesPlanScItemSDO.setStatus(null);
            salesPlanScItemSDO.setMark(null);
            SalesPlanScItemEntity editEntity = SalesPlanScItemEntity.of(salesPlanScItemSDO);
            editEntity.doEdit();
            id = String.valueOf(itemSDO.getId());
        } else {
            id = salesPlanScItemEntity.doCreate();
            return Result.success(id);
        }
        return Result.success(id);
    }

    @Nullable
    private boolean checkScItemScope(SalesPlanScItemSDO salesPlanScItemSDO) {
        log.info("SalesPlanScItemWriteServiceImpl.checkScItemScope 查询货品信息 request:{}", JSONObject.toJSONString(salesPlanScItemSDO.getScItemId()));
        Map<String, com.epoch.app.bcorder.model.dto.ScItemSDO> scItemMapByIds = salesPlanOutCommonService.getScItemMapByIds(Sets.newHashSet(salesPlanScItemSDO.getScItemId()), false);
        log.info("SalesPlanScItemWriteServiceImpl.checkScItemScope 查询货品信息 response:{}", JSONObject.toJSONString(scItemMapByIds));
        if (scItemMapByIds == null || scItemMapByIds.isEmpty() || !scItemMapByIds.containsKey(salesPlanScItemSDO.getScItemId())) {
            return true;
        }
        com.epoch.app.bcorder.model.dto.ScItemSDO scItemSDO = scItemMapByIds.get(salesPlanScItemSDO.getScItemId());
        EpochQueryPlanScItemScopeCrossDomainMatchReq request = new EpochQueryPlanScItemScopeCrossDomainMatchReq();
        request.setType(0);
        request.setScItemCode(scItemSDO.getOuterId());
        Map<String, Object> reqMap = Maps.newHashMap();
        reqMap.put("arg0", Lists.newArrayList(request));
        log.info("SalesPlanScItemWriteServiceImpl.checkScItemScope 校验分子公司创建计划货品不可超出总部设置范围 request:{}", JSONObject.toJSONString(reqMap));
        EpochQueryPlanScItemScopeCrossDomainMatchResp planScItemScopeResp = (EpochQueryPlanScItemScopeCrossDomainMatchResp)epochRESTClient.request(QUERY_PLAN_SCITEM_SCOPE_CROSS_DOMAIN_MATCH, reqMap, EpochQueryPlanScItemScopeCrossDomainMatchResp.class);
        log.info("SalesPlanScItemWriteServiceImpl.checkScItemScope 校验分子公司创建计划货品不可超出总部设置范围 response:{}", JSONObject.toJSONString(planScItemScopeResp));
        if (planScItemScopeResp == null || !planScItemScopeResp.isAllFinded()) {
            return true;
        }
        return false;
    }

    @FacadeInvoker
    @Override
    public Result<Integer> editSalesPlanScItem(SalesPlanScItemSDO salesPlanScItemSDO) {
        SalesPlanScItemEntity salesPlanScItemEntity = SalesPlanScItemEntity.of(salesPlanScItemSDO);
        Integer count = salesPlanScItemEntity.doEdit();
        if (count < 1) {
            log.error("计划货品:{}更新货品失败", JSONObject.toJSONString(salesPlanScItemSDO));
        }
        return Result.success(count);
    }

    @FacadeInvoker
    @Override
    public Result<Integer> editSalesPlanScItemState(SalesPlanScItemSDO salesPlanScItemSDO) {
        SalesPlanScItemQueryRequest planQueryRequest = new SalesPlanScItemQueryRequest();
        planQueryRequest.setId(String.valueOf(salesPlanScItemSDO.getId()));

        SalesPlanScItemSDO byId = salesPlanScItemRepository.querySalesPlanScItem(planQueryRequest);
        List<String> scItemIdList = Lists.newArrayList();
        Integer status = salesPlanScItemSDO.getStatus();
        if (Objects.equals(status, ZERO)) {
            int start = ZERO;
            int total = ONE_HUNDRED;
            List<com.epoch.app.bcorder.model.dto.SalesPlanScItemSDO> scItemList = Lists.newArrayList();
            //查询数据有限制，只能循环调用接口
            while (total == ONE_HUNDRED) {
                Result<List<com.epoch.app.bcorder.model.dto.SalesPlanScItemSDO>> scItemResult = boSalesPlanDetailIndexService.getScitemByStatus(GetScitemByStatusRequest.builder()
                        .orgSalesChannelCode(salesPlanScItemSDO.getOrgSalesChannelCode())
                        .orgBusinessChannelCode(salesPlanScItemSDO.getOrgBusinessChannelCode())
                        .scItemId(salesPlanScItemSDO.getScItemId())
                        .start(start).build());
                total = scItemResult.getTotal();
                if (scItemResult.isSuccess() && total != ZERO) {
                    scItemList.addAll(scItemResult.getResult());
                    if (total < ONE_HUNDRED) {
                        break;
                    }
                    start += ONE_HUNDRED;
                } else {
                    break;
                }
            }
            //正在使用的货品的id集合
            scItemIdList = scItemList.stream().map(com.epoch.app.bcorder.model.dto.SalesPlanScItemSDO::getScItemId).distinct().collect(Collectors.toList());
        }

//        if (status != null && !scItemIdList.contains(byId.getScItemId())) {
//            byId.setStatus(status);
//        } else {
//            return Result.fail("OTS-02-001-00-15-009", ErrorMessage.code("OTS-02-001-00-15-009", null).getDisplayErrorMessage());
//        }
        if (status != null && CollectionUtils.isEmpty(scItemIdList)) {
            byId.setStatus(status);
        } else {
            return Result.fail("OTS-02-001-00-15-009", ErrorMessage.code("OTS-02-001-00-15-009", null).getDisplayErrorMessage());
        }
        SalesPlanScItemEntity salesPlanScItemEntity = SalesPlanScItemEntity.of(byId);
        Integer count = salesPlanScItemEntity.doEdit();
        if (count < 1) {
            log.error("计划货品:{}变更计划货品状态", JSONObject.toJSONString(salesPlanScItemSDO));
            return Result.fail("OTS-02-001-00-16-037", ErrorMessage.code("OTS-02-001-00-16-037", null).getDisplayErrorMessage());
        }
        String message = status == 1 ? ErrorMessage.code("OTS-02-001-00-16-034", null).getDisplayErrorMessage() : ErrorMessage.code("OTS-02-001-00-16-035", null).getDisplayErrorMessage();
        return Result.success(count, message);
    }

    @FacadeInvoker
    @Override
    public Result<Integer> editSalesPlanScItemMark(SalesPlanScItemSDO salesPlanScItemSDO) {
        SalesPlanScItemQueryRequest planQueryRequest = new SalesPlanScItemQueryRequest();
        planQueryRequest.setId(String.valueOf(salesPlanScItemSDO.getId()));

        SalesPlanScItemSDO byId = salesPlanScItemRepository.querySalesPlanScItem(planQueryRequest);
        if (salesPlanScItemSDO.getStatus() != null) {
            byId.setMark(salesPlanScItemSDO.getMark());
        }
        SalesPlanScItemEntity salesPlanScItemEntity = SalesPlanScItemEntity.of(byId);
        Integer count = salesPlanScItemEntity.doEdit();
        if (count < 1) {
            log.error("计划货品:{}变更计划货品标记", JSONObject.toJSONString(salesPlanScItemSDO));
        }
        return Result.success(count);
    }

    /**
     * 异步刷新时间
     * 更新价格需要做权限管控，只允许分子公司调度员更新价格
     *
     * @param batchEditCostInsuranceFreightRequest
     * @return
     */
    @Override
    @FacadeInvoker
    @CommonRedisLock(redisLockPrefix = SalesPlanLockKey.BATCH_UPDATE_PLAN_SC_ITEM_PRICE_PREFIX, holdTime = 60 * 1000 * 60)
    public Result<Boolean> batchEditCostInsuranceFreight(BatchEditCostInsuranceFreightRequest batchEditCostInsuranceFreightRequest) {
        try {
            String resolveFlag = epochCacheService.get(BcOrderConstants.REDIS_CACHE_CODE(), buildRedisKey(batchEditCostInsuranceFreightRequest));
            if (SalesPlanConstants.CACHE_FLAG.equals(resolveFlag)) {
                return Result.success(null, "更新计划货品价格正在生成中，请稍待");
            }
            epochCacheService.put(BcOrderConstants.REDIS_CACHE_CODE(), buildRedisKey(batchEditCostInsuranceFreightRequest), SalesPlanConstants.CACHE_FLAG, 1200L, TimeUnit.SECONDS);
            String message = JSONObject.toJSONString(batchEditCostInsuranceFreightRequest);
            Boolean result = messageService.sendMessage("plan_product_price_update_message", "CR_SALES_PLAN_V2", "PRODUCT_PLAN_PRICE_FETCH", message);
            log.info("更新价格发送消息返回结果:{}", result);
        } catch (Exception e) {
            log.error("SalesPlanScItemWriteServiceImpl#batchEditCostInsuranceFreight_fail  更新价格发送消息异常", e);
        }
        return Result.success(null, "更新计划货品价格程序已开启，已在后台加速处理，请稍后查看处理结果");
    }

    @Override
    @FacadeInvoker
    // @EpochTransactional(appCode = "bc_order", dataSourceCode = "cr_ots", dataSourceType = "app")
    public Result<Boolean> consumePriceChange(String message) {
        log.info("SalesPlanScItemWriteServiceImpl.consumePriceChange message:" + message);
        if (StringUtils.isBlank(message)) {
            log.error("价格更新触发计划汇总消息体为空");
            return Result.success(null, "价格更新触发计划汇总消息体为空");
        }
        List<SalesPlanScItemSDO> salesPlanScItemSDOList = JSONObject.parseArray(message, SalesPlanScItemSDO.class);
        if (CollectionUtils.isEmpty(salesPlanScItemSDOList)) {
            log.warn("计划货品不存在");
            return Result.success(null, "计划货品不存在");
        }
        Map</*销售渠道id+货品id*/String, SalesPlanScItemSDO> salesPlanScItemSDOMap = salesPlanScItemSDOList.stream().collect(Collectors.toMap(salesPlanSDO ->
                salesPlanSDO.getOrgSalesChannelCode() + "_" + salesPlanSDO.getScItemId(), a -> a, (a, b) -> a));
        // 根据业务单元查询到包含当月以后的月度计划任务,状态调整中之前的更新计划明细，以后的更新计划明细+调整明细
        Set<String> orgBusinessUnitCodeSet = salesPlanScItemSDOList.stream().map(SalesPlanScItemSDO::getOrgBusinessUnitCode).collect(Collectors.toSet());
        QuerySalesPlanRequest querySalesPlanRequest = new QuerySalesPlanRequest();
        String time = DateUtils.getYear() + "-" + DateUtils.getMonth() + "-01 00:00:00";
        querySalesPlanRequest.setPlanTime(DateUtils.dateToStamp(time));//获取当前月
        querySalesPlanRequest.setOrgBusinessUnitCodes(Lists.newArrayList(orgBusinessUnitCodeSet));
        Result<List<SalesPlanSDO>> listResult = salesPlanQueryService.loadLatelySalesPlans(querySalesPlanRequest);
        if (CollectionUtils.isEmpty(listResult.getResult())) {
            // 没有查询到大于等于当前月的计划，则不需要更新计划明细/调整明细
            return Result.success(true);
        }

        // 月度计划
        List<SalesPlanSDO> editSalesPlanList = listResult.getResult().stream().filter(salesPlanSDO ->
                salesPlanSDO.getModel().equals(SalesPlanModelEnum.PLAN_MODEL.getModel()) &&
                        !salesPlanSDO.getStatus().equals(SalesPlanStatusEnum.PUBLISHED.getCode())).collect(Collectors.toList());
        // 调整计划
        List<SalesPlanSDO> editSalesPlanAdjustList = listResult.getResult().stream().filter(salesPlanSDO ->
                salesPlanSDO.getModel().equals(SalesPlanModelEnum.ADJUST_MODEL.getModel()) &&
                        salesPlanSDO.getStatus() > SalesPlanStatusEnum.PUBLISHED.getCode()).collect(Collectors.toList());
        List<SalesPlanSDO> salesPlanSDOS = Lists.newArrayList(editSalesPlanList);
        salesPlanSDOS.addAll(editSalesPlanAdjustList);
        // 月度计划 + 调整计划
        Map<Long, SalesPlanSDO> salesPlanSDOMap = salesPlanSDOS.stream().collect(Collectors.toMap(SalesPlanSDO::getId, a -> a, (a, b) -> a));
        // 货品id
        Set<String> scItemIds = salesPlanScItemSDOList.stream().map(SalesPlanScItemSDO::getScItemId).collect(Collectors.toSet());
        // 销售渠道code
        Set<String> salesChannelCodes = salesPlanScItemSDOList.stream().map(SalesPlanScItemSDO::getOrgSalesChannelCode).collect(Collectors.toSet());
        Set<String> allPlanIds = Sets.newHashSet();
        // 根据planId批量查询月度计划明细
        if (CollectionUtils.isNotEmpty(editSalesPlanList)) {
            List<String> editSalesPlanIdList = editSalesPlanList.stream().map(salesPlanSDO -> String.valueOf(salesPlanSDO.getId())).collect(Collectors.toList());
            Set<String> planIds = syncSalesPlanDetailPriceInfo(salesPlanScItemSDOMap, salesPlanSDOMap, editSalesPlanIdList, scItemIds, salesChannelCodes);
            allPlanIds.addAll(planIds);
        }
        // 根据planIds查询调整明细
        if (CollectionUtils.isNotEmpty(editSalesPlanAdjustList)) {
            List<String> editSalesPlanAdjustIdList = editSalesPlanAdjustList.stream().map(salesPlanSDO -> String.valueOf(salesPlanSDO.getId())).collect(Collectors.toList());
            Set<String> planIds = syncSalesPlanAdjustDetailPriceInfo(salesPlanScItemSDOMap, salesPlanSDOMap, editSalesPlanAdjustIdList, scItemIds, salesChannelCodes);
            allPlanIds.addAll(planIds);
        }
        // 触发月度计划汇总
        for (String allPlanId : allPlanIds) {
            Result<Boolean> collectResult = salesPlanStatService.planCollect(allPlanId);
            log.info("月度计划:{}汇总结果:{}", allPlanId, JSONObject.toJSONString(collectResult));
        }
        return Result.success(null, "价格更新完成");
    }

    private Set<String> syncSalesPlanDetailPriceInfo(Map<String, SalesPlanScItemSDO> salesPlanScItemSDOMap,
                                                     Map<Long, SalesPlanSDO> salesPlanSDOMap,
                                                     List<String> planIdList,
                                                     Set<String> scItemIds,
                                                     Set<String> salesChannelCodes) {
        Set<String> planIds = Sets.newHashSet();
        // 修改的计划明细数据
        List<SalesPlanLineSDO> salesPlanLineSDOList = new ArrayList<>();
        PageQueryPlanLineRequest pageQueryPlanLineRequest = new PageQueryPlanLineRequest();
        pageQueryPlanLineRequest.setPlanIds(planIdList);
        pageQueryPlanLineRequest.setScItemIds(Lists.newArrayList(scItemIds));
        pageQueryPlanLineRequest.setOrgSalesChannelCodes(Lists.newArrayList(salesChannelCodes));
        // 获取总数
        PageResult<List<SalesPlanLineSDO>> salesPlanLineList = salesPlanLineRepository.pageQuerySalesPlanLineList(pageQueryPlanLineRequest);
        int totalPage = (salesPlanLineList.getTotal() + SALES_PLAN_LIN_PAGE_SIZE - 1) / SALES_PLAN_LIN_PAGE_SIZE;
        for (int i = 1; i <= totalPage; i++) {
            pageQueryPlanLineRequest.setSize(SALES_PLAN_LIN_PAGE_SIZE);
            pageQueryPlanLineRequest.setPage(i);
            PageResult<List<SalesPlanLineSDO>> salesPlanLineList2 = salesPlanLineRepository.pageQuerySalesPlanLineList(pageQueryPlanLineRequest);
            if (CollectionUtils.isEmpty(salesPlanLineList2.getContent())) {
                break;
            }
            salesPlanLineSDOList.addAll(salesPlanLineList2.getContent());
        }

        if (CollectionUtils.isEmpty(salesPlanLineSDOList)) {
            log.error("没有需要更新的计划明细");
            return planIds;
        }

        for (SalesPlanLineSDO salesPlanLineSDO : salesPlanLineSDOList) {
            // 取预估折扣率
            SalesPlanSDO salesPlanSDO = salesPlanSDOMap.get(Optional.ofNullable(salesPlanLineSDO.getPlanId()).map(Long::valueOf).orElse(null));
            if (Objects.isNull(salesPlanSDO)) {
                continue;
            }
            // 取价格
            SalesPlanScItemSDO salesPlanScItemSDO = salesPlanScItemSDOMap.get(salesPlanLineSDO.getOrgSalesChannelCode() + "_" + salesPlanLineSDO.getScItemId());
            if (Objects.isNull(salesPlanScItemSDO)) {
                continue;
            }
            BigDecimal estimateDiscount = Optional.ofNullable(salesPlanSDO.getEstimateDiscount()).orElse(new BigDecimal(0));

            // 常规价
            salesPlanLineSDO.setCostInsuranceFreight(salesPlanScItemSDO.getCostInsuranceFreight());
            // 到岸价
            salesPlanLineSDO.setOutboundPrice(salesPlanScItemSDO.getOutboundPrice());
            // 折前计划金额
            long beforeMonthMoney = salesPlanLineSDO.getMonthCount() * salesPlanScItemSDO.getCostInsuranceFreight();
            salesPlanLineSDO.setBeforeMonthMoney(beforeMonthMoney);
            // 折后计划金额
            salesPlanLineSDO.calculateMonthMoney(estimateDiscount);
            // 折前任务金额
            long beforeTaskMoney = salesPlanLineSDO.getTaskCount() * salesPlanScItemSDO.getCostInsuranceFreight();
            salesPlanLineSDO.setBeforeTaskMoney(beforeTaskMoney);
            // 折后任务金额
            salesPlanLineSDO.calculateTaskMoney(estimateDiscount);
            // 折前调整金额
            long beforeAdjustMoney = salesPlanLineSDO.getAdjustCount() * salesPlanScItemSDO.getCostInsuranceFreight();
            salesPlanLineSDO.setBeforeAdjustMoney(beforeAdjustMoney);
            // 折后调整金额
            salesPlanLineSDO.calculateAdjustMoney(estimateDiscount);

            // 根据状态计算满足度
            if (salesPlanLineSDO.getStatus() <= SalesPlanStatusEnum.TO_BE_PUBLISHED.getCode()) {
                // 待发布之前计算计划满足度
                BigDecimal beforeContractSatisfaction = CalculatePercentage.retainTwo(beforeMonthMoney, salesPlanLineSDO.getBeforeMonthContractMoney());
                salesPlanLineSDO.setBeforeContractSatisfaction(beforeContractSatisfaction);
                BigDecimal contractSatisfaction = CalculatePercentage.retainTwo(salesPlanLineSDO.getMonthMoney(), salesPlanLineSDO.getMonthContractMoney());
                salesPlanLineSDO.setContractSatisfaction(contractSatisfaction);
                // 到岸折前金额
                long beforeMonthOutboundMoney = salesPlanLineSDO.getMonthCount() * salesPlanLineSDO.getOutboundPrice();
                salesPlanLineSDO.setBeforeMonthOutboundMoney(beforeMonthOutboundMoney);
                // 到岸折后金额
                salesPlanLineSDO.calculateMonthOutboundMoney(estimateDiscount);
            } else if (Objects.equals(salesPlanLineSDO.getStatus(), SalesPlanStatusEnum.PUBLISHED.getCode())) {
                // 已发布计算任务满足度
                BigDecimal beforeContractSatisfaction = CalculatePercentage.retainTwo(beforeTaskMoney, salesPlanLineSDO.getBeforeMonthContractMoney());
                salesPlanLineSDO.setBeforeContractSatisfaction(beforeContractSatisfaction);
                BigDecimal contractSatisfaction = CalculatePercentage.retainTwo(salesPlanLineSDO.getTaskMoney(), salesPlanLineSDO.getMonthContractMoney());
                salesPlanLineSDO.setContractSatisfaction(contractSatisfaction);
                // 到岸折前金额
                long beforeMonthOutboundMoney = salesPlanLineSDO.getTaskCount() * salesPlanLineSDO.getOutboundPrice();
                salesPlanLineSDO.setBeforeMonthOutboundMoney(beforeMonthOutboundMoney);
                // 到岸折后金额
                salesPlanLineSDO.calculateMonthOutboundMoney(estimateDiscount);
            } else {
                // 调整中以后计算调整满足度
                BigDecimal beforeContractSatisfaction = CalculatePercentage.retainTwo(beforeAdjustMoney, salesPlanLineSDO.getBeforeMonthContractMoney());
                salesPlanLineSDO.setBeforeContractSatisfaction(beforeContractSatisfaction);
                BigDecimal contractSatisfaction = CalculatePercentage.retainTwo(salesPlanLineSDO.getAdjustMoney(), salesPlanLineSDO.getMonthContractMoney());
                salesPlanLineSDO.setContractSatisfaction(contractSatisfaction);
                // 到岸折前金额
                long beforeMonthOutboundMoney = salesPlanLineSDO.getAdjustCount() * salesPlanLineSDO.getOutboundPrice();
                salesPlanLineSDO.setBeforeMonthOutboundMoney(beforeMonthOutboundMoney);
                // 到岸折后金额
                salesPlanLineSDO.calculateMonthOutboundMoney(estimateDiscount);
            }
            salesPlanLineRepository.edit(salesPlanLineSDO);
            planIds.add(salesPlanLineSDO.getPlanId());
        }
        return planIds;
    }

    private Set<String> syncSalesPlanAdjustDetailPriceInfo(Map<String, SalesPlanScItemSDO> salesPlanScItemSDOMap,
                                                           Map<Long, SalesPlanSDO> salesPlanSDOMap,
                                                           List<String> adjustIdList,
                                                           Set<String> scItemIds,
                                                           Set<String> salesChannelCodes) {
        Set<String> planIds = Sets.newHashSet();
        // 修改的调整明细
        List<SalesPlanAdjustDetailSDO> salesPlanAdjustDetailSDOList = new ArrayList<>();
        PageQueryPlanAdjustDetailRequest pageQueryPlanAdjustDetailRequest = new PageQueryPlanAdjustDetailRequest();
        pageQueryPlanAdjustDetailRequest.setAdjustIds(adjustIdList);
        pageQueryPlanAdjustDetailRequest.setOrgSalesChannelCodes(Lists.newArrayList(salesChannelCodes));
        pageQueryPlanAdjustDetailRequest.setScItemIds(Lists.newArrayList(scItemIds));
        // 获取总数
        PageResult<List<SalesPlanAdjustDetailSDO>> salesPlanAdjustDetailList = salesPlanAdjustDetailRepository.pageQuerySalesPlanAdjustDetailList(pageQueryPlanAdjustDetailRequest);
        int totalPage2 = (salesPlanAdjustDetailList.getTotal() + SALES_PLAN_ADJUST_PAGE_SIZE - 1) / SALES_PLAN_ADJUST_PAGE_SIZE;
        for (int i = 1; i <= totalPage2; i++) {
            pageQueryPlanAdjustDetailRequest.setSize(SALES_PLAN_ADJUST_PAGE_SIZE);
            pageQueryPlanAdjustDetailRequest.setPage(i);
            PageResult<List<SalesPlanAdjustDetailSDO>> salesPlanAdjustDetailList2 = salesPlanAdjustDetailRepository.pageQuerySalesPlanAdjustDetailList(pageQueryPlanAdjustDetailRequest);
            if (CollectionUtils.isEmpty(salesPlanAdjustDetailList2.getContent())) {
                break;
            }
            salesPlanAdjustDetailSDOList.addAll(salesPlanAdjustDetailList2.getContent());
        }

        if (CollectionUtils.isEmpty(salesPlanAdjustDetailSDOList)) {
            log.error("没有需要更新的计划调整明细");
            return planIds;
        }

        for (SalesPlanAdjustDetailSDO salesPlanAdjustDetailSDO : salesPlanAdjustDetailSDOList) {
            // 取预估折扣率
            SalesPlanSDO salesPlanSDO = salesPlanSDOMap.get(Optional.ofNullable(salesPlanAdjustDetailSDO.getPlanId()).map(Long::valueOf).orElse(null));
            if (Objects.isNull(salesPlanSDO)) {
                continue;
            }
            // 取价格
            SalesPlanScItemSDO salesPlanScItemSDO = salesPlanScItemSDOMap.get(salesPlanAdjustDetailSDO.getOrgSalesChannelCode() + "_" + salesPlanAdjustDetailSDO.getScItemId());
            if (Objects.isNull(salesPlanScItemSDO)) {
                continue;
            }

            // 到岸价
            salesPlanAdjustDetailSDO.setCostInsuranceFreight(salesPlanScItemSDO.getCostInsuranceFreight());
            salesPlanAdjustDetailSDO.setOutboundPrice(salesPlanScItemSDO.getOutboundPrice());
            BigDecimal estimateDiscount = Optional.ofNullable(salesPlanSDO.getEstimateDiscount()).orElse(new BigDecimal(0));
            // 折前计划金额
            long beforeMonthMoney = salesPlanAdjustDetailSDO.getMonthCount() * salesPlanScItemSDO.getCostInsuranceFreight();
            salesPlanAdjustDetailSDO.setBeforeMonthMoney(beforeMonthMoney);
            // 折后计划金额
            salesPlanAdjustDetailSDO.calculateMonthMoney(estimateDiscount);
            // 折前任务金额
            long beforeTaskMoney = salesPlanAdjustDetailSDO.getTaskCount() * salesPlanScItemSDO.getCostInsuranceFreight();
            salesPlanAdjustDetailSDO.setBeforeTaskMoney(beforeTaskMoney);
            // 折后任务金额
            salesPlanAdjustDetailSDO.calculateTaskMoney(estimateDiscount);
            // 折前调整金额
            long beforeAdjustMoney = salesPlanAdjustDetailSDO.getAdjustCount() * salesPlanScItemSDO.getCostInsuranceFreight();
            salesPlanAdjustDetailSDO.setBeforeAdjustMoney(beforeAdjustMoney);
            // 折后调整金额
            salesPlanAdjustDetailSDO.calculateAdjustMoney(estimateDiscount);

            // 根据状态计算满足度
            if (salesPlanAdjustDetailSDO.getStatus() <= SalesPlanStatusEnum.TO_BE_PUBLISHED.getCode()) {
                // 待发布之前计算计划满足度
                BigDecimal beforeContractSatisfaction = CalculatePercentage.retainTwo(beforeMonthMoney, salesPlanAdjustDetailSDO.getBeforeMonthContractMoney());
                salesPlanAdjustDetailSDO.setBeforeContractSatisfaction(beforeContractSatisfaction);
                BigDecimal contractSatisfaction = CalculatePercentage.retainTwo(salesPlanAdjustDetailSDO.getMonthMoney(), salesPlanAdjustDetailSDO.getMonthContractMoney());
                salesPlanAdjustDetailSDO.setContractSatisfaction(contractSatisfaction);
                // 到岸折前金额
                long beforeMonthOutboundMoney = salesPlanAdjustDetailSDO.getMonthCount() * salesPlanAdjustDetailSDO.getOutboundPrice();
                salesPlanAdjustDetailSDO.setBeforeMonthOutboundMoney(beforeMonthOutboundMoney);
                // 到岸折后金额
                salesPlanAdjustDetailSDO.calculateMonthOutboundMoney(estimateDiscount);
            } else if (Objects.equals(salesPlanAdjustDetailSDO.getStatus(), SalesPlanStatusEnum.PUBLISHED.getCode())) {
                // 已发布计算任务满足度
                BigDecimal beforeContractSatisfaction = CalculatePercentage.retainTwo(beforeTaskMoney, salesPlanAdjustDetailSDO.getBeforeMonthContractMoney());
                salesPlanAdjustDetailSDO.setBeforeContractSatisfaction(beforeContractSatisfaction);
                BigDecimal contractSatisfaction = CalculatePercentage.retainTwo(salesPlanAdjustDetailSDO.getTaskMoney(), salesPlanAdjustDetailSDO.getMonthContractMoney());
                salesPlanAdjustDetailSDO.setContractSatisfaction(contractSatisfaction);
                // 到岸折前金额
                long beforeMonthOutboundMoney = salesPlanAdjustDetailSDO.getTaskCount() * salesPlanAdjustDetailSDO.getOutboundPrice();
                salesPlanAdjustDetailSDO.setBeforeMonthOutboundMoney(beforeMonthOutboundMoney);
                // 到岸折后金额
                salesPlanAdjustDetailSDO.calculateMonthOutboundMoney(estimateDiscount);
            } else {
                // 调整中以后计算调整满足度
                BigDecimal beforeContractSatisfaction = CalculatePercentage.retainTwo(beforeAdjustMoney, salesPlanAdjustDetailSDO.getBeforeMonthContractMoney());
                salesPlanAdjustDetailSDO.setBeforeContractSatisfaction(beforeContractSatisfaction);
                BigDecimal contractSatisfaction = CalculatePercentage.retainTwo(salesPlanAdjustDetailSDO.getAdjustMoney(), salesPlanAdjustDetailSDO.getMonthContractMoney());
                salesPlanAdjustDetailSDO.setContractSatisfaction(contractSatisfaction);
                // 到岸折前金额
                long beforeMonthOutboundMoney = salesPlanAdjustDetailSDO.getAdjustCount() * salesPlanAdjustDetailSDO.getOutboundPrice();
                salesPlanAdjustDetailSDO.setBeforeMonthOutboundMoney(beforeMonthOutboundMoney);
                // 到岸折后金额
                salesPlanAdjustDetailSDO.calculateMonthOutboundMoney(estimateDiscount);
            }
            salesPlanAdjustDetailRepository.edit(salesPlanAdjustDetailSDO);
            planIds.add(salesPlanAdjustDetailSDO.getPlanId());
        }
        return planIds;
    }

    /**
     * 获取到岸价和常规销售价
     *
     * @param salesPlanScItemSDO
     */
    private void getPrice(SalesPlanScItemSDO salesPlanScItemSDO) {
        if (StringUtil.isBlank(salesPlanScItemSDO.getOrgBusinessUnitCode())) {
            throw new FacadeException("OTS-01-003-01-15-023");
        }
        if (StringUtil.isBlank(salesPlanScItemSDO.getOrgSalesOrganizationCode())) {
            throw new FacadeException("OTS-01-003-01-15-022");
        }
        if (StringUtil.isBlank(salesPlanScItemSDO.getOrgBusinessChannelCode())) {
            throw new FacadeException("OTS-01-003-01-15-030");
        }
        // 查询货品
        ScItemSDO scItemSDO = salesPlanScItemRepository.queryScItemById(salesPlanScItemSDO.getScItemId());
        if (Objects.isNull(scItemSDO)) {
            throw new FacadeException("OTS-01-005-02-15-001");
        }
        if (StringUtil.isBlank(scItemSDO.getOuterId())) {
            throw new FacadeException("OTS-01-005-02-15-002");
        }
        List<String> ids = new ArrayList<>();
        ids.add(salesPlanScItemSDO.getOrgBusinessUnitCode());
        ids.add(salesPlanScItemSDO.getOrgSalesOrganizationCode());
        BaselineGetOrganizationByIdsRequest baselineGetOrganizationByIdsRequest = BaselineGetOrganizationByIdsRequest.builder().ids(ids).build();
        Object result = baseDataService.baselineGetOrganizationByIds(baselineGetOrganizationByIdsRequest);
        List<OrganizationSDO> organizationSDOList = buildResponse(result);
        if (CollectionUtils.isEmpty(organizationSDOList)) {
            throw new FacadeException("OTS-01-003-01-16-003");
        }
        Map<String, OrganizationSDO> organizationSDOMap = organizationSDOList.stream().collect(Collectors.toMap(OrganizationSDO::getId, a -> a, (a, b) -> a));
        if (MapUtils.isEmpty(organizationSDOMap)) {
            throw new FacadeException("OTS-01-003-01-16-003");
        }
        OrganizationSDO orgSalesOrganizationSDO = organizationSDOMap.get(salesPlanScItemSDO.getOrgSalesOrganizationCode());
        if (Objects.isNull(orgSalesOrganizationSDO)) {
            throw new FacadeException("OTS-01-003-01-16-003");
        }
        OrganizationSDO orgBusinessUnitSDO = organizationSDOMap.get(salesPlanScItemSDO.getOrgBusinessUnitCode());
        if (Objects.isNull(orgBusinessUnitSDO)) {
            throw new FacadeException("OTS-01-003-01-16-003");
        }

        PriceQueryRequest priceQueryRequest = new PriceQueryRequest();
        List<DimensionPropertyInfoRequest> dimensionPropertyInfoRequestList = Lists.newArrayList();
        // 常规销售价构建参数
        dimensionPropertyInfoRequestList.add(buildCommonSalesPrice(salesPlanScItemSDO, scItemSDO, orgSalesOrganizationSDO));
        // 到岸价构建参数
        dimensionPropertyInfoRequestList.add(buildCFIPrice(salesPlanScItemSDO, scItemSDO, orgBusinessUnitSDO));

        Map<String, String> featuresMap = Maps.newHashMap();
        featuresMap.put("outCodeToInnerCode", "out_code_to_inner_code");
        priceQueryRequest.setDimensionPropertyInfoRequestList(dimensionPropertyInfoRequestList);
        priceQueryRequest.setFeatures(featuresMap);
        log.info("SalesPlanScItemWriteServiceImpl.getPrice.priceQueryRequest:" + JSONObject.toJSONString(priceQueryRequest));
        Result<PriceQueryResponse> priceQueryResponseResult = priceQueryService.batchQueryPrice(priceQueryRequest);
        log.info("SalesPlanScItemWriteServiceImpl.getPrice.priceQueryResponseResult:" + JSONObject.toJSONString(priceQueryResponseResult));
        SalesPlanCommonService.resultCheck(priceQueryResponseResult, "OTS-02-001-00-16-001");
        if (CollectionUtils.isEmpty(priceQueryResponseResult.getResult().getItemPriceResponseList())) {
            throw new FacadeException("OTS-02-001-00-16-016");
        }
        List<ItemPriceResponse> itemPriceResponseList = priceQueryResponseResult.getResult().getItemPriceResponseList();
//        ItemPriceResponse commonSalesPrice = itemPriceResponseList.get(0);
//        ItemPriceResponse cFISalesPrice = itemPriceResponseList.get(1);
        List<ItemPriceResponse> itemPriceResponses = itemPriceResponseList.stream().filter(x -> (null != x.getMoneyAmout() && x.getMoneyAmout() > 0)).collect(Collectors.toList());
//        if (Objects.isNull(commonSalesPrice)||Objects.isNull(commonSalesPrice.getMoneyAmout())||commonSalesPrice.getMoneyAmout()<=0){
//            throw new FacadeException("OTS-02-001-00-16-017");
//        }
//
//        if (Objects.isNull(cFISalesPrice)||Objects.isNull(cFISalesPrice.getMoneyAmout())||cFISalesPrice.getMoneyAmout()<=0){
//            throw new FacadeException("OTS-02-001-00-16-017");
//        }

        if (itemPriceResponseList.size() != itemPriceResponses.size()) {
            throw new FacadeException("OTS-02-001-00-16-016");
        }
        Map<String, ItemPriceResponse> itemPriceResponseMap = itemPriceResponses.stream().collect(Collectors.toMap(x -> x.getItemId() + x.getFeatures().get("priceType"), a -> a, (a, b) -> a));
        // 常规价
        ItemPriceResponse costInsuranceFreightResponse = itemPriceResponseMap.get(scItemSDO.getOuterId() + PriceTypeEnum.ZP01.getCode());
        if (Objects.isNull(costInsuranceFreightResponse)) {
            throw new FacadeException("OTS-02-001-00-16-018");
        }
        // 到岸价
        ItemPriceResponse outboundPriceResponse = itemPriceResponseMap.get(scItemSDO.getOuterId() + PriceTypeEnum.ZMN1.getCode());
        if (Objects.isNull(outboundPriceResponse)) {
            throw new FacadeException("OTS-02-001-00-16-019");
        }
        salesPlanScItemSDO.setCostInsuranceFreight(costInsuranceFreightResponse.getMoneyAmout());
        salesPlanScItemSDO.setOutboundPrice(outboundPriceResponse.getMoneyAmout());
    }

    /**
     * 构造到岸价请求参数
     *
     * @param scItemSDO
     * @param salesPlanScItemSDO
     * @param orgBusinessUnitSDO
     * @return
     */
    private DimensionPropertyInfoRequest buildCFIPrice(SalesPlanScItemSDO salesPlanScItemSDO, ScItemSDO scItemSDO, OrganizationSDO orgBusinessUnitSDO) {
        // 组装 货品请求数据
        MaterialInfoRequest materialInfoRequest2 = new MaterialInfoRequest();
        // 货品
        materialInfoRequest2.setMaterialCode(scItemSDO.getOuterId());
        // 货品组
        materialInfoRequest2.setScItemGroupCode("11");

        // 组织 组织请求数据
        PlaceInfoRequest placeInfoRequest2 = new PlaceInfoRequest();

        //20230925，乌鲁木齐分子公司总部销售组织6004  其他分子公司总部销售组织6000
        QuerySuperiorSalesOrganizationRequest querySuperiorSalesOrganizationRequest = new QuerySuperiorSalesOrganizationRequest();
        querySuperiorSalesOrganizationRequest.setOrganizationId(salesPlanScItemSDO.getOrgBusinessUnitCode());
        Result<OrganizationSDO> querySuperiorSalesOrgResult = organizationQueryService.querySuperiorSalesOrganization(querySuperiorSalesOrganizationRequest);
        OrganizationSDO superiorSalesOrgSDO = querySuperiorSalesOrgResult.getResult();

        // 销售组织
        placeInfoRequest2.setOrgSalesOrganizationCode(superiorSalesOrgSDO.getCode());
        // 查询工厂
        CustomerSaleScopeSDO customerSaleScopeSDO = getFactoryCode(superiorSalesOrgSDO,orgBusinessUnitSDO);
        // SAP工厂
        placeInfoRequest2.setFactoryCode(Optional.ofNullable(customerSaleScopeSDO.getStoreHouse()).orElse(null));
        // 销售渠道
        placeInfoRequest2.setSalesDepartment(Optional.ofNullable(customerSaleScopeSDO.getOutOrgSalesChannelCode()).orElse(null));
        // 业务渠道
        //2022.08.02计划货品范围优化 新建计划货品获取到岸价 通过业务渠道 新建页面带入
//        placeInfoRequest2.setChannelCode("20");
        placeInfoRequest2.setChannelCode(salesPlanScItemSDO.getOrgBusinessChannelCode());
        // 销售部门
        placeInfoRequest2.setSalesGroup(Optional.ofNullable(customerSaleScopeSDO.getOutOrgSalesDepartmentCode()).orElse(null));
        // 部门
        placeInfoRequest2.setDepartmentCode(Optional.ofNullable(customerSaleScopeSDO.getOutOrgSalesChannelCode()).orElse(null));
        // 定价区域
        placeInfoRequest2.setPriceArea(Optional.ofNullable(customerSaleScopeSDO.getSalesArea()).orElse(null));

        HumanInfoRequest humanInfoRequest2 = new HumanInfoRequest();
        // 客户
        humanInfoRequest2.setCustomerCode(Optional.ofNullable(customerSaleScopeSDO.getCustomerCode()).orElse(null));

        // 请求查询价格参数
        DimensionPropertyInfoRequest propertyInfoRequest = new DimensionPropertyInfoRequest();
        propertyInfoRequest.setPriceTypeId(PriceTypeEnum.ZMN1.getCode());
        propertyInfoRequest.setPriceUseDate(new Date());
        propertyInfoRequest.setMaterialInfoRequest(materialInfoRequest2);
        propertyInfoRequest.setPlaceInfoRequest(placeInfoRequest2);
        propertyInfoRequest.setHumanInfoRequest(humanInfoRequest2);
        return propertyInfoRequest;
    }

    /**
     * 构造常规销售价
     *
     * @param salesPlanScItemSDO
     * @param scItemSDO
     * @param orgSalesOrganizationSDO
     * @return
     */
    private DimensionPropertyInfoRequest buildCommonSalesPrice(SalesPlanScItemSDO salesPlanScItemSDO, ScItemSDO scItemSDO, OrganizationSDO orgSalesOrganizationSDO) {
        // 组装 货品请求数据
        MaterialInfoRequest materialInfoRequest = new MaterialInfoRequest();
        materialInfoRequest.setMaterialCode(scItemSDO.getOuterId());
        materialInfoRequest.setScItemGroupCode("11");
        // 组装 组织请求数据
        PlaceInfoRequest placeInfoRequest = new PlaceInfoRequest();
        placeInfoRequest.setSalesUnitCode(scItemSDO.getFeatures().get("unitName"));
        placeInfoRequest.setOrgSalesOrganizationCode(orgSalesOrganizationSDO.getOutCode());
        // 查组织关联渠道
        //2022.08.02 计划货品范围优化: 计划货品新增获取常规价 通过业务渠道 前端新建页面带入
//        String channelOutCode = "";
//        IdQueryRequest idQueryRequest = new IdQueryRequest();
//        idQueryRequest.setId(salesPlanScItemSDO.getOrgSalesChannelCode());
//        try {
//            Result<List<OrganizationRelationSDO>> orgChannelRelationByOrgId = organizationQueryService.getOrgChannelRelationByOrgId(idQueryRequest);
//            SalesPlanCommonService.resultCheck(orgChannelRelationByOrgId, "OTS-01-003-01-16-005");
//            List<OrganizationRelationSDO> organizationRelation = orgChannelRelationByOrgId.getResult();
//            channelOutCode = organizationRelation.get(0).getOutCode();
//        } catch (Exception e) {
//            throw new FacadeException("OTS-01-003-01-16-006");
//        }
//        if (StringUtil.isBlank(channelOutCode)) {
//            throw new FacadeException("OTS-01-003-01-16-006");
//        }
//        placeInfoRequest.setChannelCode(channelOutCode);
        placeInfoRequest.setChannelCode(salesPlanScItemSDO.getOrgBusinessChannelCode());
        // 请求查询价格参数
        DimensionPropertyInfoRequest propertyInfoRequest = new DimensionPropertyInfoRequest();
        propertyInfoRequest.setPriceTypeId(PriceTypeEnum.ZP01.getCode());
        propertyInfoRequest.setPriceUseDate(new Date());
        propertyInfoRequest.setMaterialInfoRequest(materialInfoRequest);
        propertyInfoRequest.setPlaceInfoRequest(placeInfoRequest);
        propertyInfoRequest.setHumanInfoRequest(new HumanInfoRequest());
        return propertyInfoRequest;
    }

    private CustomerSaleScopeSDO getFactoryCode(OrganizationSDO superiorSalesOrgSDO, OrganizationSDO orgBusinessUnitSDO) {
        if (StringUtil.isBlank(orgBusinessUnitSDO.getBizId())) {
            throw new FacadeException("OTS-01-003-01-15-024");
        }
        String outCode = "";
        String bizId = orgBusinessUnitSDO.getBizId();
        BatchQueryCompanyRequest companyRequest = BatchQueryCompanyRequest.builder().ids(Lists.newArrayList(bizId)).build();
        Map map = (Map) bcOrderService.batchQueryCompany(companyRequest);
        if (MapUtils.isNotEmpty(map)) {
            Map<String, Object> resultMap = (Map<String, Object>) map.get("result");
            if (MapUtils.isNotEmpty(resultMap)) {
                List<Map<String, Object>> resultList = (List<Map<String, Object>>) resultMap.get("content");
                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(resultList)) {
                    Map<String, Object> resultSubMap = resultList.get(0);
                    outCode = (String) resultSubMap.get("outCode");
                }
            }
        }
        if (StringUtil.isBlank(outCode)) {
            throw new FacadeException("OTS-01-003-01-15-025");
        }
        PageQueryCustomerScope2Request pageQueryCustomerScope2Request = PageQueryCustomerScope2Request.builder()
                .customerCode(outCode)
                .orgSaleOrganizationCode(superiorSalesOrgSDO.getId())
                .itemGroup("11")
                .channelCode("20")
                .build();
        PageQueryCustomerScope2Response pageQueryCustomerScope2Response = crPlatformEnhanceService.pageQueryCustomerScope2(pageQueryCustomerScope2Request);
        if (null == pageQueryCustomerScope2Response || null == pageQueryCustomerScope2Response.getResult() || pageQueryCustomerScope2Response.getResult().size() < 1) {
            throw new FacadeException("OTS-02-001-00-16-041");
        }
        CustomerSaleScopeSDO customerSaleScopeSDO = pageQueryCustomerScope2Response.getResult().stream().findFirst().get();
        if (StringUtil.isBlank(customerSaleScopeSDO.getStoreHouse())) {
            throw new FacadeException("OTS-02-001-00-16-041");
        }
        return customerSaleScopeSDO;
    }

    private List<OrganizationSDO> buildResponse(Object response) {
        List<OrganizationSDO> organizationSDOList = new ArrayList<>();
        Map saleMap = (Map) response;
        JSONArray result = com.alibaba.fastjson.JSONObject.parseObject(com.alibaba.fastjson.JSONObject.toJSONString(saleMap)).getJSONArray("result");
        if (CollectionUtils.isNotEmpty(result)) {
            for (int i = 0; i < result.size(); i++) {
                OrganizationSDO sdo = new OrganizationSDO();
                com.alibaba.fastjson.JSONObject organizationSDO = result.getJSONObject(i).getJSONObject("organizationSDO");
                String id = Optional.ofNullable(organizationSDO.getString("id")).orElse(null);
                String name = Optional.ofNullable(organizationSDO.getString("name")).orElse(null);
                String outCode = Optional.ofNullable(organizationSDO.getString("outCode")).orElse(null);
                String bizId = Optional.ofNullable(organizationSDO.getString("bizId")).orElse(null);
                sdo.setId(id);
                sdo.setName(name);
                sdo.setOutCode(outCode);
                sdo.setBizId(bizId);
                organizationSDOList.add(sdo);
            }
        }
        return organizationSDOList;
    }

    private String buildRedisKey(BatchEditCostInsuranceFreightRequest request) {
        return SalesPlanConstants.getPlanScItemPriceUpdatePrefix(request.getRelatedOrganizationId() + request.getRelatedOrganizationType());
    }


    /**
     * 批量更新计划货品范围的状态
     *
     * @param batchUpdateScItem
     * @return
     */
    @Override
    public Result<Boolean> batchUpdateStatus(BatchUpdateScItemStatusRequest batchUpdateScItem) {
        //判断是否传参
        if (CollectionUtils.isEmpty(batchUpdateScItem.getIds())) {
            throw new FacadeException("OTS-02-002-02-15-008");
        }
        if (Objects.isNull(batchUpdateScItem.getStatus())) {
            throw new FacadeException("OTS-02-001-00-16-038");
        }
        //如果不是空的情况 根据传入的ids进行批量更新该数据的状态
        List<Long> ids = batchUpdateScItem.getIds();
        ids.forEach(id -> {
            SalesPlanScItemSDO scItemSDO = new SalesPlanScItemSDO();
            scItemSDO.setId(id);
            scItemSDO.setStatus(batchUpdateScItem.getStatus());
            Integer count = salesPlanScItemRepository.batchUpdateStatus(scItemSDO);
            if (count < 0) {
                throw new FacadeException("OTS-02-001-00-16-039");
            }
        });
        return Result.success(true);
    }
}
